package com.shujia.homework

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

import java.text.{ParseException, SimpleDateFormat}
import java.util.Date

object LogDataCompute {
  def main(args: Array[String]): Unit = {

    val conf: SparkConf = new SparkConf().setMaster("local").setAppName("LogDataCompute")
    val sc = new SparkContext(conf)
    val cleanRDD: RDD[(String, String)] = sc
      .textFile("spark_code/data/test.log")
      /*
              1.1 过滤出字段数量少于8的脏数据，并检查脏数据类型是什么 日志字段如下：（event_time,url,method,status,sip,user_uip,action_prepend,action_client）
              1.2 如果url和请求时间在同一时刻相同，那么认为是数据请求有误 需要过滤
              1.3 状态码非200的为错误无效访问
              1.4 请求时间未记录，或不规范，则需要去除
       */
      .filter(
        line => line.split("\t").size == 8
      )
      .map {
        case line => {
          val splitRes: Array[String] = line.split("\t")
          (splitRes(0), splitRes(1), splitRes(2), splitRes(3), splitRes(4), splitRes(5), splitRes(6), splitRes(7))
        }
      }
      .filter {
        case (event_time, url, method, status, sip, user_uip, action_prepend, action_client) => {
          status.equals("200")
        }
      }
      .map {
        case (event_time, url, method, status, sip, user_uip, action_prepend, action_client) => {
          // 对Event_time做类型转换
          var clean_time: String = ""

          // 如果格式为25 那么可以对其进行格式转换
          if (event_time.size == 25) {
            try {
              val dateFormat1 = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss")
              val date: Date = dateFormat1.parse(event_time)
              val dateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
              clean_time = dateFormat2.format(date)
            } catch {
              case e:ParseException => {
                println(s"event_time:${event_time} 数据格式有误")
              }
            }
          }
          (clean_time, url)
        }
      }
      // 对于无效数据，可以先过滤 之后再做去重操作
      .filter {
        case (clean_time, url) => {
          clean_time.nonEmpty
        }
      }
      .distinct()

    /*
        2.需求计算
              1.每日注册用户请求数，URL中请求类型为 Registered，则认为是注册用户请求
              2.统计每日活跃用户  (actionName请求参数为StartLearn和BuyCourse)
       */
    cleanRDD
      .filter {
        case (clean_time, url) => {
          url.contains("&actionName=Registered&")
        }
      }
      .groupBy {
        case (clean_time, url) => {
          clean_time.substring(0,10)
        }
      }
      .mapValues(_.size)
      .foreach(println)

  }
}
